package com.xrh.xdemo.service.service;


import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xrh.core.bean.CommonPage;
import com.xrh.core.bean.CommonResult;
import com.xrh.core.exceptions.BusinessException;
import com.xrh.core.utils.XAssert;
import com.xrh.xdemo.api.dto.entity.SysRoleDTO;
import com.xrh.xdemo.api.dto.extend.RoleInfoDTO;
import com.xrh.xdemo.api.enums.SysRoleEnum;
import com.xrh.xdemo.api.request.addRequest.SysRoleAddRequest;
import com.xrh.xdemo.api.request.queryRequest.SysRoleQueryRequest;
import com.xrh.xdemo.api.request.updateRequest.RoleBindMenuRequest;
import com.xrh.xdemo.api.request.updateRequest.RoleBindUsersRequest;
import com.xrh.xdemo.api.request.updateRequest.SysRoleUpdateRequest;
import com.xrh.xdemo.service.aspects.OperateTraceAspect;
import com.xrh.xdemo.service.entity.SysRoleEntity;
import com.xrh.xdemo.service.mapper.SysRoleMapper;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SysRoleService {

	@Resource
	SysRoleMapper sysRoleMapper;
	
	@Resource
	UserVsRoleService userVsRoleService;
	
	@Resource
	RoleVsMenuService roleVsMenuService;
	
	/**
	 * @function 初始化角色
	 * @author 肖荣辉
	 * @date 2023年12月17日
	*/
	public void initRole() {
		
		log.info("初始化系统角色start");
		
		for(SysRoleEnum item : SysRoleEnum.values()) {
			
			SysRoleEntity entity = createEntityIfRoleNotExist(item.name(), item.getShowName());
			
			int count = entity.getId() == null ? sysRoleMapper.insert(entity) : sysRoleMapper.updateById(entity);
			
			log.info("初始化角色:{}成功 , count : {}" , item.getShowName() , count);
			
		}
		
		log.info("初始化系统角色end");
		
	}
	
	/**
	 * @function 如果角色编号不存在则创建一个
	 * @param roleNo
	 * @author 肖荣辉
	 * @date 2023年12月17日
	*/
	private SysRoleEntity createEntityIfRoleNotExist(String roleNo , String roleName) {
		
		SysRoleEntity entity = findEntityByRoleNo(roleNo);
		
		entity = entity == null ? new SysRoleEntity() : entity;
		
		entity.setRoleNo(roleNo);
		entity.setRoleName(roleName);
		entity.setSysFlag(1);
		entity.setRemark("系统角色");
		
		return entity;
	}
	
	/**
	 * @function 根据角色编号获取entity
	 * @param roleNo
	 * @author 肖荣辉
	 * @date 2023年12月17日
	*/
	public SysRoleEntity findEntityByRoleNo(String roleNo) {
		
		LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<SysRoleEntity>();
		
		queryWrapper.eq(SysRoleEntity::getRoleNo, roleNo);
		
		queryWrapper.last("limit 1");
		
		return sysRoleMapper.selectOne(queryWrapper);
	}
	
	/**
	 * @function 获取用户拥有的角色DTO
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public List<RoleInfoDTO> getRoleInfoDTOListByUserId(Long userId){
		return BeanUtil.copyToList(getRoleEntityListByUserId(userId), RoleInfoDTO.class);
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	 */
	public List<RoleInfoDTO> getUserRoleInfoDTOList(){
		return BeanUtil.copyToList(getUserRoleEntityList(), RoleInfoDTO.class);
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public List<SysRoleEntity> getUserRoleEntityList(){
		
		Set<Long> roleIds = getUserRoleIds();
		
		if(CollUtil.isEmpty(roleIds))
			return new ArrayList<SysRoleEntity>();
		
		return sysRoleMapper.selectBatchIds(roleIds);
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	 */
	public List<SysRoleEntity> getRoleEntityListByUserId(Long userId){
		
		Set<Long> roleIds = getRoleIdsByUserId(userId);
		
		if(CollUtil.isEmpty(roleIds))
			return new ArrayList<SysRoleEntity>();
		
		return sysRoleMapper.selectBatchIds(roleIds);
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	*/
	public Set<Long> getUserRoleIds(){
		return userVsRoleService.getUserRoleIds();
	}
	
	/**
	 * @function 获取用户拥有的角色id
	 * @author 肖荣辉
	 * @date 2023年12月8日
	 */
	public Set<Long> getRoleIdsByUserId(Long userId){
		return userVsRoleService.getRoleIdsByUserId(userId);
	}
	
	/**
	 * @function 检查角色编号是否存在
	 * @author 肖荣辉
	 * @date 2023年12月16日
	*/
	public void checkRoleNoExist(String oldRoleNo , String newRoleNo) {
		
		if(oldRoleNo != null && oldRoleNo.equals(newRoleNo))
			return;
		
		LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<SysRoleEntity>();
		
		queryWrapper.eq(SysRoleEntity::getRoleNo, newRoleNo);
		
		queryWrapper.last("limit 1");
		
		XAssert.isTrue(sysRoleMapper.selectOne(queryWrapper) == null, "编号"+newRoleNo+"已经存在");
		
	}
	
	/**
	 * @function 新增SysRole
	 * @param sysRoleAddRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	@Transactional
	public Long addSysRole(SysRoleAddRequest sysRoleAddRequest) {
		
		//检查角色编号是否存在
		checkRoleNoExist(null, sysRoleAddRequest.getRoleNo());
		
		SysRoleEntity sysRoleEntity = new SysRoleEntity();
		
		BeanUtil.copyProperties(sysRoleAddRequest , sysRoleEntity , CopyOptions.create().ignoreNullValue());
		
		sysRoleMapper.insert(sysRoleEntity);
		
		return sysRoleEntity.getId();
	}
	
	/**
	 * @function 删除SysRole
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public void deleteSysRoleById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
			
		SysRoleEntity sysRoleEntity = sysRoleMapper.selectById(id);
		
		if(sysRoleEntity == null)
			throw new BusinessException("id不合法");
		
		XAssert.isTrue(sysRoleEntity.getSysFlag() == 0, "系统角色不允许删除");
		
		UpdateWrapper<SysRoleEntity> updateWrapper = new UpdateWrapper<>();
		updateWrapper.eq("id", id);
		
		//因为注解了@TableLogic , 自动会把删除标志位设置为1 
		sysRoleMapper.delete(updateWrapper);
		
		//操作轨迹标题
		OperateTraceAspect.setTitle(sysRoleEntity.getRoleName());
		
	}

	/**
	 * @function 修改SysRole
	 * @param sysRoleUpdateRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public void updateSysRole(SysRoleUpdateRequest sysRoleUpdateRequest) {
		
		if(sysRoleUpdateRequest.getId() == null)
			throw new BusinessException("id不能为空");
		
		SysRoleEntity sysRoleEntity = sysRoleMapper.selectById(sysRoleUpdateRequest.getId());
		
		if(sysRoleEntity == null)
			throw new BusinessException("id不合法");
		
		XAssert.isTrue(sysRoleEntity.getSysFlag() == 0, "系统角色不允许修改");
		
		//检查角色编号是否存在
		checkRoleNoExist(sysRoleEntity.getRoleNo(), sysRoleUpdateRequest.getRoleNo());
		
		BeanUtil.copyProperties(sysRoleUpdateRequest , sysRoleEntity , CopyOptions.create().ignoreNullValue());
		
		sysRoleMapper.updateById(sysRoleEntity);
		
	}

	/**
	 * @function 根据ID查询SysRole Entity
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public SysRoleEntity findSysRoleEntityById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
			
		SysRoleEntity sysRoleEntity = sysRoleMapper.selectById(id);
		
		return sysRoleEntity;
	}
	
	/**
	 * @function 根据ID查询SysRole DTO
	 * @param id
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public SysRoleDTO findSysRoleById(Long id) {
		
		if(id == null)
			throw new BusinessException("id不能为空");
	
		SysRoleEntity sysRoleEntity = sysRoleMapper.selectById(id);
		
		SysRoleDTO  sysRoleDTO = BeanUtil.toBean(sysRoleEntity , SysRoleDTO.class);
		
		return sysRoleDTO;
	}

	/**
	 * @function 根据SysRoleQueryVo查询SysRole列表
	 * @param sysRoleQueryRequest
	 * @author 肖荣辉
	 * @date 2023-12-08 15:17:26
	*/
	public CommonResult<CommonPage<SysRoleDTO>> findSysRoleList(SysRoleQueryRequest sysRoleQueryRequest) {
		
		Page<SysRoleEntity> page = sysRoleQueryRequest.createPage();

		QueryWrapper<SysRoleEntity> queryWrapper = sysRoleQueryRequest.createQuery();
		
		sysRoleMapper.selectPage(page, queryWrapper);
		
		List<SysRoleDTO> dtoList = BeanUtil.copyToList(page.getRecords() , SysRoleDTO.class);
		
		return CommonResult.success(CommonPage.create(sysRoleQueryRequest.getPageNum() , sysRoleQueryRequest.getPageSize() , dtoList, page.getTotal()));
	}
	
    /**
   	 * @function 角色绑定菜单
   	 * @param bindRequest
   	 * @author 肖荣辉
   	 * @date 2023-12-08 15:17:26
   	*/
	@Transactional
	public void roleBindMenus(RoleBindMenuRequest bindRequest) {

		SysRoleEntity sysRoleEntity = findSysRoleEntityById(bindRequest.getId());
		
		XAssert.isTrue(sysRoleEntity != null , "角色id不合法");
		
		//重置角色和菜单的绑定关系信息
		roleVsMenuService.resetRoleVsMenu(sysRoleEntity.getId() , bindRequest.getMenuIds());
		
	}
	
    /**
   	 * @function 角色绑定用户
   	 * @param bindRequest
   	 * @author 肖荣辉
   	 * @date 2023-12-08 15:17:26
   	*/
	public void roleBindUsers(RoleBindUsersRequest bindRequest) {
		
		SysRoleEntity sysRoleEntity = findSysRoleEntityById(bindRequest.getId());
		
		XAssert.isTrue(sysRoleEntity != null , "角色id不合法");
		
		//角色绑定用户
		userVsRoleService.roleBindUsers(sysRoleEntity.getId(), bindRequest.getUserIds());
		
	}
	
    /**
   	 * @function 角色解绑用户
   	 * @param bindRequest
   	 * @author 肖荣辉
   	 * @date 2023-12-08 15:17:26
   	*/
	public void roleUnbindUsers(RoleBindUsersRequest bindRequest) {
		
		SysRoleEntity sysRoleEntity = findSysRoleEntityById(bindRequest.getId());
		
		XAssert.isTrue(sysRoleEntity != null , "角色id不合法");
		
		userVsRoleService.roleUnBindUsers(sysRoleEntity.getId(), bindRequest.getUserIds());
		
	}
	
	
	
}
